@file:Suppress("unused", "SameParameterValue", "MemberVisibilityCanBePrivate")

package com.example.base.ui.dialog

import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.*
import androidx.annotation.StyleRes
import androidx.databinding.DataBindingUtil
import androidx.databinding.ViewDataBinding
import androidx.fragment.app.DialogFragment
import androidx.fragment.app.FragmentManager
import com.example.base.R
import com.example.base.ext.screenWidth

/**  Dialog 基类  **/
abstract class UIDialog<VDB : ViewDataBinding> : DialogFragment() {

    private lateinit var window: Window
    private val height: Int = 0

    /** The selectDialog key listener  **/
    private var keyListener: DialogInterface.OnKeyListener =
        object : DialogInterface.OnKeyListener {
            override fun onKey(dialog: DialogInterface, keyCode: Int, event: KeyEvent): Boolean {
                if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_UP) {
                    // commit this handle
                    onBackPressed()
                    return true
                }

                // prevent mask other key
                return false
            }
        }

    /**  get the selectDialog custom layout  **/
    abstract fun getContentRes(): Int

    /**  the selectDialog is showing now  **/
    val isShowing: Boolean get() = requireDialog().isShowing

    /**  ViewDataBinding 对象  **/
    lateinit var mBinding: VDB

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        arguments?.apply {
            initParams(this)
        }
    }

    /**  初始化 Fragment 的初始数据时可重写该方法, 直接使用 arguments 参数即  **/
    protected open fun initParams(arguments: Bundle) {}

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?, savedInstanceState: Bundle?
    ): View? {
        initWindow()

        // 需要用android.R.id.content这个view
        mBinding = DataBindingUtil.inflate(
            inflater,
            getContentRes(),
            window.findViewById(android.R.id.content),
            false
        )

        val width = screenWidth / 6 * 5
        setSize(width, height)
        return mBinding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        mBinding.lifecycleOwner = this
        initData()
    }

    /**  init view and data and events  **/
    protected open fun initData() {

    }

    /**  设置 Dialog 的初始样式  **/
    private fun initWindow() {
        requireDialog().setOnKeyListener(keyListener)
        requireDialog().requestWindowFeature(Window.FEATURE_NO_TITLE)
        window = requireDialog().window!!

        window.apply {
            setWindowAnimations(windowAnimations)
            clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM)
            setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_MASK_STATE)
            setDimAmount(0.4f)
            //注意此处
            setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        }

        isCancelable = isSupportCancel
    }

    /**  定义 Dialog 的显示/消失 动画  **/
    @StyleRes
    open val windowAnimations: Int = R.style.DialogTheme_AnimStyle

    /**
     * 是否支持点击外侧隐藏 Dialog
     * @return 默认不支持, 要想支持请重写该方法并返回 true
     */
    open val isSupportCancel: Boolean = false

    /**
     * set this selectDialog size
     *
     * @param width  the selectDialog width
     * @param height the selectDialog height
     */
    open fun setSize(width: Int, height: Int) = setSizeAndLocation(width, height, Gravity.CENTER)

    /**
     * 设置窗口大小和显示位置
     *
     * @param width   窗口宽度
     * @param height  窗口高度
     * @param gravity 显示位置
     */
    protected fun setSizeAndLocation(width: Int, height: Int, gravity: Int) {
        var mWidth = width
        var mHeight = height
        val params = window.attributes
        params.gravity = gravity
        if (0 == mHeight)
            mHeight = WindowManager.LayoutParams.WRAP_CONTENT
        if (0 == mWidth)
            mWidth = WindowManager.LayoutParams.WRAP_CONTENT
        params.alpha = 0.96f
        window.attributes = params
        window.setLayout(mWidth, mHeight)
    }

    /**  this is the tag of class show method  **/
    fun show(manager: FragmentManager) = super.show(manager, javaClass.simpleName)

    /**  set the selectDialog key keyListener  **/
    fun setOnKeyListener(listener: DialogInterface.OnKeyListener) {
        this.keyListener = listener
        requireDialog().setOnKeyListener(this.keyListener)
    }

    /**  set this selectDialog Dismiss Listener  **/
    fun setOnDismissListener(listener: DialogInterface.OnDismissListener) =
        requireDialog().setOnDismissListener(listener)

    /**  on back key pressed will be call back  **/
    protected open fun onBackPressed() = dismiss()

    override fun onDestroyView() {
        mBinding.unbind()
        super.onDestroyView()
    }

}